package com.xin.di.uav.common.annotate;

import com.xin.di.uav.common.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Arrays;

@Aspect
@Component
@RequiredArgsConstructor
public class ReSubmitAspect {
    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

    @Around("@annotation(reSubmit)")
    public Object around(ProceedingJoinPoint joinPoint, ReSubmit reSubmit) throws Throwable {
        String key = generateKey(joinPoint, reSubmit.key());
        // 使用 SETNX + EXPIRE 原子操作（Redis 2.6.12+ 支持 SET with NX/EX）
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(
                key, "1", Duration.ofSeconds(reSubmit.expire())
        );
        if (locked == null || !locked) {
            throw new BusinessException("操作过于频繁，请稍后重试");
        }
        try {
            return joinPoint.proceed();
        } finally {
            // 可选：主动删除键（若业务执行时间远小于过期时间）
            // redisTemplate.delete(key);
        }
    }

    private String generateKey(ProceedingJoinPoint joinPoint, String customKey) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        return "debounce:" + customKey + ":" + Arrays.toString(joinPoint.getArgs());
    }
}
